#include "helper.h"
#include "monitor.h"
#include "reg.h"
#include "memory.h"
//需要完成指令 addi.w、add.w、lu12i.w、pcaddu12i、or、ori、andi、xor、beq、bne、st.w、ld.w、st.b、ld.b

extern uint32_t instr;
extern char assembly[80];
void OutputFile();
/* decode I12-type instrucion with unsigned immediate */
static void decode_ui12_type(uint32_t instr) {
	//option op_src1源寄存器 op_src2立即数源操作数 op_dest目的寄存器
	op_src1->type = OP_TYPE_REG;
	op_src1->reg = (instr >> 5) & 0x0000001F;
	op_src1->val = reg_w(op_src1->reg);//reg_w宏 输入寄存器号 返回寄存器的32位数值

	op_src2->type = OP_TYPE_IMM;
	op_src2->imm = (instr >> 10) & 0x00000FFF;
	op_src2->val = op_src2->imm;

	op_dest->type = OP_TYPE_REG;
	op_dest->reg = instr & 0x0000001F;
}


make_helper(ori) {

	decode_ui12_type(instr);//解析当前指令
	reg_w(op_dest->reg) = op_src1->val | op_src2->val;

	//使用sprintf函数将处理后的指令格式化为汇编字符串 存储到assembly中
	sprintf(assembly, "ori\t%s,\t%s,\t0x%03x", REG_NAME(op_dest->reg), REG_NAME(op_src1->reg), op_src2->imm);
	OutputFile();
}

//TODO:完成addi_w andi st.w ld.w st.b ld.b
make_helper(addi_w){
	decode_ui12_type(instr);
	reg_w(op_dest->reg) = op_src1->val + op_src2->val;
	sprintf(assembly, "addi.w\t%s,\t%s,\t0x%03x", REG_NAME(op_dest->reg), REG_NAME(op_src1->reg), op_src2->imm);
	OutputFile();
}
make_helper(andi){
	decode_ui12_type(instr);
	reg_w(op_dest->reg) = op_src1->val & op_src2->val;
	sprintf(assembly, "andi.w\t%s,\t%s,\t0x%03x", REG_NAME(op_dest->reg), REG_NAME(op_src1->reg), op_src2->imm);
	OutputFile();
}
make_helper(st_w){
	decode_ui12_type(instr);
	//立即数是12位 要进行符号扩展成32位
	uint32_t temp;
	int is_negative = (op_src2->val & 0x800);
	if(is_negative) temp = (op_src2->val | 0xFFFFF000);
	else temp = op_src2->val;//正数不用进行扩展
	uint32_t vaddr = temp + op_src1->val;
	mem_write(vaddr , 4 , reg_w(op_dest->reg));
	sprintf(assembly, "st.w\t%s,\t%s,\t0x%03x", REG_NAME(op_dest->reg), REG_NAME(op_src1->reg), op_src2->imm);
	OutputFile();
}

make_helper(st_b){
	decode_ui12_type(instr);
	//立即数是12位 要进行符号扩展成32位
	uint32_t temp;
	int is_negative = (op_src2->val & 0x800);
	if(is_negative) temp = (op_src2->val | 0xFFFFF000);
	else temp = op_src2->val;//正数不用进行扩展
	uint32_t vaddr = temp + op_src1->val;
	mem_write(vaddr , 1 , reg_w(op_dest->reg));
	sprintf(assembly, "st.b\t%s,\t%s,\t0x%03x", REG_NAME(op_dest->reg), REG_NAME(op_src1->reg), op_src2->imm);
	OutputFile();
}

make_helper(ld_w){
	decode_ui12_type(instr);
	//立即数是12位 要进行符号扩展成32位
	uint32_t temp;
	int is_negative = (op_src2->val & 0x800);
	if(is_negative) temp = (op_src2->val | 0xFFFFF000);
	else temp = op_src2->val;//正数不用进行扩展
	uint32_t vaddr = temp + op_src1->val;
	reg_w(op_dest->reg) = mem_read(vaddr,4);
	sprintf(assembly, "ld.w\t%s,\t%s,\t0x%03x", REG_NAME(op_dest->reg), REG_NAME(op_src1->reg), op_src2->imm);
	OutputFile();
}

make_helper(ld_b){
	decode_ui12_type(instr);
	//立即数是12位 要进行符号扩展成32位
	uint32_t temp;
	int is_negative = (op_src2->val & 0x800);
	if(is_negative) temp = (op_src2->val | 0xFFFFF000);
	else temp = op_src2->val;//正数不用进行扩展
	uint32_t vaddr = temp + op_src1->val;
	reg_w(op_dest->reg) = mem_read(vaddr,1);
	sprintf(assembly, "ld.b\t%s,\t%s,\t0x%03x", REG_NAME(op_dest->reg), REG_NAME(op_src1->reg), op_src2->imm);
	OutputFile();
}

make_helper(sltui){

    decode_ui12_type(instr);
    // 判断源寄存器的值是否小于立即数，如果小于则结果为 1，否则为 0
    reg_w(op_dest->reg) = (op_src1->val < op_src2->imm) ? 1 : 0;
    sprintf(assembly, "sltui\t%s,\t%s,\t0x%03x", REG_NAME(op_dest->reg), REG_NAME(op_src1->reg), op_src2->imm);
	OutputFile();
}

